from typing import Dict, Any, Optional
from sqlalchemy import text
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
import time

from app.database import get_db, db_manager
from app.redis_client import redis_client
from app.utils.logging import get_logger

# 创建路由器
router = APIRouter(prefix="/health", tags=["health"])

# 创建日志对象
logger = get_logger(__name__)

async def check_database_connection() -> Dict[str, Any]:
    """
    检查数据库连接状态
    """
    start_time = time.time()
    try:
        # 使用数据库管理器的会话上下文
        async with db_manager.session() as session:
            # 执行简单查询
            result = await session.execute(text("SELECT 1 as test_connection"))
            test_result = result.scalar_one()
            
            # 计算查询耗时
            duration = time.time() - start_time
            
            if test_result == 1:
                return {
                    "status": "healthy",
                    "response_time_ms": round(duration * 1000, 2),
                    "connection_pool": {
                        "size": db_manager.engine.pool.size(),
                        "checkedin": db_manager.engine.pool.checkedin(),
                        "overflow": db_manager.engine.pool.overflow(),
                        "checkedout": db_manager.engine.pool.checkedout(),
                    }
                }
            else:
                return {
                    "status": "unhealthy",
                    "error": "Database connection test returned unexpected result",
                    "response_time_ms": round(duration * 1000, 2)
                }
    except Exception as e:
        duration = time.time() - start_time
        logger.error(f"Database health check failed: {str(e)}")
        return {
            "status": "unhealthy",
            "error": str(e),
            "error_type": type(e).__name__,
            "response_time_ms": round(duration * 1000, 2)
        }

async def check_redis_connection() -> Dict[str, Any]:
    """
    检查Redis连接状态
    """
    start_time = time.time()
    try:
        # 执行PING命令
        ping_result = await redis_client._redis.ping()
        
        # 计算查询耗时
        duration = time.time() - start_time
        
        if ping_result:
            # 获取Redis信息
            info = await redis_client._redis.info()
            
            return {
                "status": "healthy",
                "response_time_ms": round(duration * 1000, 2),
                "redis_version": info.get("redis_version", "unknown"),
                "connected_clients": info.get("connected_clients", "unknown"),
                "used_memory_human": info.get("used_memory_human", "unknown"),
            }
        else:
            return {
                "status": "unhealthy",
                "error": "Redis PING command returned unexpected result",
                "response_time_ms": round(duration * 1000, 2)
            }
    except Exception as e:
        duration = time.time() - start_time
        logger.error(f"Redis health check failed: {str(e)}")
        return {
            "status": "unhealthy",
            "error": str(e),
            "error_type": type(e).__name__,
            "response_time_ms": round(duration * 1000, 2)
        }

@router.get("/db")
async def database_health_check():
    """
    数据库健康检查接口
    """
    result = await check_database_connection()
    if result["status"] == "unhealthy":
        raise HTTPException(status_code=503, detail=result)
    return result

@router.get("/redis")
async def redis_health_check():
    """
    Redis健康检查接口
    """
    result = await check_redis_connection()
    if result["status"] == "unhealthy":
        raise HTTPException(status_code=503, detail=result)
    return result

@router.get("/all")
async def full_health_check():
    """
    全面健康检查接口
    检查所有依赖服务的状态
    """
    start_time = time.time()
    
    # 并行检查数据库和Redis
    db_result = await check_database_connection()
    redis_result = await check_redis_connection()
    
    # 计算总耗时
    total_duration = time.time() - start_time
    
    # 汇总结果
    result = {
        "status": "healthy" if db_result["status"] == "healthy" and redis_result["status"] == "healthy" else "unhealthy",
        "response_time_ms": round(total_duration * 1000, 2),
        "database": db_result,
        "redis": redis_result,
    }
    
    if result["status"] == "unhealthy":
        raise HTTPException(status_code=503, detail=result)
    
    return result
